﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.IO;
using System.Xml.Serialization;

namespace SlaktDataReader
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {

        public ObservableCollection<Location> Locations { get { return Globals.Locations; } set { Globals.Locations = value; } }
        public ObservableCollection<Book> Books { get { return Globals.Books; } set { Globals.Books = value; } }

        #region DeathBook
        //public CollectionView TheDead { get; set; }
        public ObservableCollection<DeathBookRecord> TheDead { get; set; }
        public DeathBook CurDeathBook { get; set; }
        public DeathBookRecord CurItem { get; set; }

        void CurDeathBook_ReadSuccess(object sender, EventArgs e)
        {
            PopulateCurDeathBook();
        }

        private void bAdd_Click(object sender, RoutedEventArgs e)
        {
            if (CurDeathBook == null)
            {
                CurDeathBook = new DeathBook();
            }

            if (CurDeathBook.Items == null)
            {
                CurDeathBook.Items = new ObservableCollection<DeathBookRecord>();
            }

            CurDeathBook.Items.Add(CurItem);

            // Update List
            CurItem = new DeathBookRecord();
            CurItem.RowID = (CurDeathBook.Items.Count * 10);
            Notify("CurItem");
            PopulateCurDeathBook();
        }

        private void PopulateCurDeathBook()
        {
            if (CurDeathBook != null)
            {


                if (CurDeathBook.Items != null)
                {
                    if (txtDeathFilter.Text == "")
                    {
                        TheDead = new ObservableCollection<DeathBookRecord>(CurDeathBook.Items);
                    }
                    else
                    {
                        string tm = txtDeathFilter.Text.ToUpper();
                        var L = (from f in CurDeathBook.Items
                                 where (f.Address.ToUpper().Contains(tm)
                                     || f.FirstName.ToUpper().Contains(tm) || f.SurName.ToUpper().Contains(tm)
                                     )
                                 select f);
                        TheDead = new ObservableCollection<DeathBookRecord>(L.ToList());
                        //CurBirthBook.Parish
                    }
                }
            }
            else
            {
                CurDeathBook = new DeathBook();
                CurDeathBook.Items = new ObservableCollection<DeathBookRecord>();
            }

            Notify("TheDead");
        }

        private void lstDeadBook_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lstDeadBook.SelectedItem != null)
            {
                CurItem = lstDeadBook.SelectedItem as DeathBookRecord;
                Notify("CurItem");
            }
        }

        private void bBackFromDeathBook_Click(object sender, RoutedEventArgs e)
        {
            grdDead.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void txtDeathFilter_TextChanged(object sender, TextChangedEventArgs e)
        {
            PopulateCurDeathBook();
        }


        #endregion

        #region BirthBook
        public ObservableCollection<BirthBookRecord> TheBorn { get; set; }
        public BirthBook CurBirthBook { get; set; }
        public BirthBookRecord CurBirthItem { get; set; }



        void CurBirthBook_ReadSuccess(object sender, EventArgs e)
        {
            txtBirthFilter.Text = "";
            PopulateCurBirthBook();
        }

        private void PopulateCurBirthBook()
        {
            if (CurBirthBook != null)
            {
                if (CurBirthBook.Items != null)
                {
                    if (txtBirthFilter.Text == "")
                    {
                        TheBorn = new ObservableCollection<BirthBookRecord>(CurBirthBook.Items);
                    }
                    else
                    {
                        string tm = txtBirthFilter.Text.ToUpper();
                        var L = (from f in CurBirthBook.Items
                                 where (f.Address.ToUpper().Contains(tm)
                                     || f.FatherFirstName.ToUpper().Contains(tm) || f.FatherSurName.ToUpper().Contains(tm)
                                     || f.FirstName.ToUpper().Contains(tm) || f.SurName.ToUpper().Contains(tm)
                                     || f.MotherFirstName.ToUpper().Contains(tm) || f.MotherSurName.ToUpper().Contains(tm))
                                 select f);
                        TheBorn = new ObservableCollection<BirthBookRecord>(L.ToList());
                    }
                }
            }
            else
            {
                CurBirthBook = new BirthBook();
                CurBirthBook.Items = new ObservableCollection<BirthBookRecord>();
            }

            Notify("TheBorn");
        }

        private void lstBirthBook_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lstBirthBook.SelectedItem != null)
            {
                CurBirthItem = lstBirthBook.SelectedItem as BirthBookRecord;
                Notify("CurBirthItem");
            }
        }

        private void bBackFromBirthBook_Click(object sender, RoutedEventArgs e)
        {
            grdBorn.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void txtBirthFilter_TextChanged(object sender, TextChangedEventArgs e)
        {
            PopulateCurBirthBook();
        }

        #endregion

        #region Marriages
        public ObservableCollection<MarriageBookRecord> TheMarriaged { get; set; }
        public MarriageBook CurMarriageBook { get; set; }
        public MarriageBookRecord CurMItem { get; set; }

        void CurMarriageBook_ReadSuccess(object sender, EventArgs e)
        {
            txtMarriageFilter.Text = "";
            PopulateCurMarriageBook();
        }

        private void PopulateCurMarriageBook()
        {
            if (CurMarriageBook != null)
            {
                if (CurMarriageBook.Items != null)
                {
                    if (txtMarriageFilter.Text == "")
                    {
                        TheMarriaged = new ObservableCollection<MarriageBookRecord>(CurMarriageBook.Items);
                    }
                    else
                    {
                        string tm = txtMarriageFilter.Text.ToUpper();
                        var L = (from f in CurMarriageBook.Items
                                 where (f.MaleAddress.ToUpper().Contains(tm) || f.FemaleAddress.ToUpper().Contains(tm)
                                     || f.MaleFirstName.ToUpper().Contains(tm) || f.MaleSurName.ToUpper().Contains(tm)
                                     || f.FemaleFirstName.ToUpper().Contains(tm) || f.FemaleSurName.ToUpper().Contains(tm)
                                     ) 
                                 select f);
                        TheMarriaged = new ObservableCollection<MarriageBookRecord>(L.ToList());
                    }
                }
            }
            else
            {
                CurMarriageBook = new MarriageBook();
                CurMarriageBook.Items = new ObservableCollection<MarriageBookRecord>();
            }

            Notify("TheMarriaged");
        }

        private void lvMarriageBook_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lvMarriageBook.SelectedItem != null)
            {
                CurMItem = lvMarriageBook.SelectedItem as  MarriageBookRecord;
                Notify("CurMItem");
            }
        }

        private void bBackFromMarriageBook_Click(object sender, RoutedEventArgs e)
        {
            grdMarriage.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void txtMarriageFilter_TextChanged(object sender, TextChangedEventArgs e)
        {
            PopulateCurMarriageBook();
        }

        private void bAddMarriage_Click(object sender, RoutedEventArgs e)
        {

        }

        #endregion

        #region General



        public MainWindow()
        {
            Globals.SetDefaultValues();
            InitializeComponent();

            Globals.Locations = new ObservableCollection<Location>();
            Globals.Books = new ObservableCollection<Book>();
            CurrentLocationParent = new Location();
            CurrentLocationParent.LocationID = Guid.Empty;
            CurrentLocationParent.LocationName = "SVERIGE";
            CurrentLocationParent.Level = 0;

            
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            CurDeathBook = new DeathBook();
            CurDeathBook.ReadSuccess += new EventHandler(CurDeathBook_ReadSuccess);

            CurBirthBook = new BirthBook();
            CurBirthBook.ReadSuccess += new EventHandler(CurBirthBook_ReadSuccess);

            CurMarriageBook = new MarriageBook();
            CurMarriageBook.ReadSuccess += new EventHandler(CurMarriageBook_ReadSuccess);

            // Read Locations
            ReadLocations();

            // Read Books
            ReadBooks();

            Notify("CurrentLocations");
            Notify("CurrentLocationParent");
        }

        private void notifysettings()
        {
            Notify("DownloadBooks");
            Notify("BookDownloadPath");
        }

        /// <summary>
        /// Read available books from disc.
        /// </summary>
        private void ReadBooks()
        {
            string BookFile = System.IO.Directory.GetCurrentDirectory() + "\\books.dat";
            //using (var iso = IsolatedStorageFile.GetUserStoreForApplication())


            try
            {
                using (FileStream stream = new FileStream(BookFile, FileMode.OpenOrCreate))
                {
                    if (stream.Length > 0)
                    {
                        XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<Book>));
                        using (var reader = new StreamReader(stream))
                        {
                            Books = xs.Deserialize(reader) as ObservableCollection<Book>;
                            Notify("CurrBooks");
                        }
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// Save available books to disc.
        /// </summary>
        private void WriteBooks()
        {
            string BooksFile = System.IO.Directory.GetCurrentDirectory() + "\\books.dat";
            //using (var iso = IsolatedStorageFile.GetUserStoreForApplication())

            try
            {
                using (FileStream stream = new FileStream(BooksFile, FileMode.Create))
                {
                    XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<Book>));
                    using (var writer = new StreamWriter(stream))
                    {
                        xs.Serialize(writer, Books);
                    }
                }
            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.Message, "WriteBooks");
            }
        }

        /// <summary>
        /// Read available locatios from Disc.
        /// </summary>
        private void ReadLocations()
        {
            string LocationsFile = System.IO.Directory.GetCurrentDirectory() + "\\locations.dat";
            //using (var iso = IsolatedStorageFile.GetUserStoreForApplication())


            try
            {
                using (FileStream stream = new FileStream(LocationsFile, FileMode.OpenOrCreate))
                {
                    if (stream.Length > 0)
                    {
                        XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<Location>));
                        using (var reader = new StreamReader(stream))
                        {
                            Locations = xs.Deserialize(reader) as ObservableCollection<Location>;
                            Notify("Locations");
                        }
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// Write available locations to disc
        /// </summary>
        private void WriteLocations()
        {
            string LocationsFile = System.IO.Directory.GetCurrentDirectory() + "\\locations.dat";
            //using (var iso = IsolatedStorageFile.GetUserStoreForApplication())

            try
            {
                using (FileStream stream = new FileStream(LocationsFile, FileMode.Create))
                {
                    XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<Location>));
                    using (var writer = new StreamWriter(stream))
                    {
                        xs.Serialize(writer, Locations);
                    }
                }
            }
            catch { }

        }

        /// <summary>
        /// Wrapper for PropertyChanged
        /// </summary>
        /// <param name="propertyName"></param>
        private void Notify(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            WriteLocations();
            WriteBooks();
        }

        #endregion

        #region Settings
        public bool DownloadBooks
        {
            get { return Globals.DownloadBooks; }
            set { Globals.DownloadBooks = value; }
        }

        public string BookDownloadPath
        {
            get { return Globals.BookDownloadPath; }
            set { Globals.BookDownloadPath = value; }
        }
        #endregion

        #region Locations

        public Location CurrentLocationParent { get; set; }

        public ObservableCollection<Location> CurrentLocations
        {
            get
            {
                Guid g;
                if (CurrentLocationParent == null)
                {
                    g = Guid.Empty;
                }
                else
                {
                    g = CurrentLocationParent.LocationID;
                }
                Notify("UppButtonVisibility");
                if (Locations == null || Locations.Count == 0)
                {
                    return null;
                }
                return new ObservableCollection<Location>((from L in Locations where L.ParentID == g orderby L.LocationName select L));
            }
        }

        public Visibility UppButtonVisibility
        {
            get
            {
                if (CurrentLocationParent != null)
                    if (CurrentLocationParent.Level == 0)
                        return Visibility.Collapsed;

                return System.Windows.Visibility.Visible;
            }
        }

        private void bAddLocation_Click(object sender, RoutedEventArgs e)
        {
            winLocation wnd = new winLocation();
            wnd.loc.ParentID = CurrentLocationParent.LocationID;
            wnd.loc.Level = CurrentLocationParent.Level + 1;
            if (wnd.ShowDialog() == true)
            {
                Globals.Locations.Add(wnd.loc);
                Notify("CurrentLocations");
            }
        }

        private void lstLocations_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            LocationNavigationEnter();
        }

        private void lstLocations_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Notify("CurLocationType");
            Notify("LocationBookCount");
            Notify("LocationBooks");
        }

        public string CurLocationType
        {
            get
            {
                if (lstLocations.SelectedItem != null)
                {
                    Location l = lstLocations.SelectedItem as Location;
                    switch (l.Level)
                    {
                        case 0:
                            return "LAND";
                        case 1:
                            return "LÄN";
                        case 2:
                            return "SOCKEN";
                        default:
                            return "OTHER";
                    }
                }
                else
                {
                    return "";
                }
            }
        }

        /// <summary>
        /// Get current book count for this location
        /// </summary>
        public int LocationBookCount
        {
            get
            {
                if (lstLocations.SelectedItem != null)
                {
                    Location l = lstLocations.SelectedItem as Location;
                    return (from b in Books where b.Location == l.LocationID select b).Count();
                }
                else
                { return 0; }
            }
        }

        /// <summary>
        /// Gets all books for the current location
        /// </summary>
        public ObservableCollection<Book> LocationBooks
        {
            get
            {
                if (LocationBookCount > 0)
                {
                    Location l = lstLocations.SelectedItem as Location;

                    return new ObservableCollection<Book>((from b in Books where b.Location == l.LocationID select b).ToList());
                }
                else
                {
                    return null;
                }
            }
        }


        private void LocationNavigationEnter()
        {
            if (CurrentLocationParent != null)
            {
                if (CurrentLocationParent.Level >= 0)
                {
                    if (lstLocations.SelectedItems.Count == 1)
                    {
                        CurrentLocationParent = lstLocations.SelectedItem as Location;
                        Notify("CurrentLocationParent");
                        Notify("CurrentLocations");
                        // Alter template maybe ?
                    }
                }
            }
        }

        private void LocationNavigationLeave()
        {
            if (CurrentLocationParent != null)
            {
                if (CurrentLocationParent.Level > 1)
                {
                    CurrentLocationParent = Globals.Locations.Single(f => f.LocationID == CurrentLocationParent.ParentID);
                    Notify("CurrentLocationParent");
                    Notify("CurrentLocations");
                }
                else if (CurrentLocationParent.Level == 1)
                {
                    CurrentLocationParent = new Location();
                    CurrentLocationParent.Level = 0;
                    CurrentLocationParent.LocationID = Guid.Empty;
                    CurrentLocationParent.LocationName = "SVERIGE";
                    Notify("CurrentLocationParent");
                    Notify("CurrentLocations");
                }

            }
        }

        private void bEditLocation_Click(object sender, RoutedEventArgs e)
        {
            EditLocation();
        }

        private void EditLocation()
        {
            if (lstLocations.SelectedItems.Count == 1)
            {
                winLocation wnd = new winLocation();
                wnd.loc = lstLocations.SelectedItem as Location;
                wnd.ShowDialog();
            }
        }

        private void bLocationUp_Click(object sender, RoutedEventArgs e)
        {
            LocationNavigationLeave();
        }

        #endregion

        #region Books

        public ObservableCollection<Book> CurrBooks
        {
            get
            {
                if (Globals.Books != null)
                    return new ObservableCollection<Book>(from I in Globals.Books orderby I.FriendlyName select I);
                return null;
            }
            set
            {
                Globals.Books = value;
            }
        }

        private void bAddBook_Click(object sender, RoutedEventArgs e)
        {
            Wins.winBook wnd = new Wins.winBook();
            if (wnd.ShowDialog() == true)
            {
                Globals.Books.Add(wnd.bk);
                Notify("CurrBooks");
                if (wnd.HideGoto == false && wnd.GotoBook == true)
                {
                    GotoBook(wnd.bk);
                }
            }
        }

        private void GotoBook(Book book)
        {
            if (book == null) return;

            switch (book.BookType)
            {
                case BookTypes.Born:
                    Pages.pgBirth pg = new Pages.pgBirth();
                    pg.BirthBook = book;
                    pg.parentgrid = grdBook;
                    pg.BirthBookData.ClearBook();
                    pg.BirthBookData.CopyFromBook(book);
                    if (pg.BirthBookData.ReadBook())
                    {
                        frmBooks.Navigate(pg);
                        grdBook.Visibility = System.Windows.Visibility.Visible;
                    }
                    break;

                case BookTypes.Dead:
                    Pages.pgDeath dpg = new Pages.pgDeath();
                    dpg.DeathBook = book;
                    dpg.parentgrid = grdBook;
                    dpg.DeathBookData.ClearBook();
                    dpg.DeathBookData.CopyFromBook(book);

                    if (dpg.DeathBookData.ReadBook())
                    {
                        frmBooks.Navigate(dpg);
                        grdBook.Visibility = System.Windows.Visibility.Visible;
                    }

                    //CurDeathBook.ClearBook();
                    //CurDeathBook.CopyFromBook(book);
                    //CurDeathBook.ReadBook();
                    ////PopulateCurDeathBook();
                    //grdDead.Visibility = System.Windows.Visibility.Visible;
                    break;
                case BookTypes.Marriages:
                    Pages.pgMarriage mpg = new Pages.pgMarriage();
                    mpg.MarriageBook = book;
                    mpg.parentgrid = grdBook;
                    mpg.MarriageBookData.ClearBook();
                    mpg.MarriageBookData.CopyFromBook(book);

                    if (mpg.MarriageBookData.ReadBook())
                    {
                        frmBooks.Navigate(mpg);
                        grdBook.Visibility = System.Windows.Visibility.Visible;
                    }

                    //CurMarriageBook.ClearBook();
                    //CurMarriageBook.CopyFromBook(book);
                    //CurMarriageBook.ReadBook();
                    //grdMarriage.Visibility = System.Windows.Visibility.Visible;
                    break;

                case BookTypes.HouseCall:
                    Pages.pgHouseCall chpg = new Pages.pgHouseCall();
                    chpg.HouseCallBook = book;
                    chpg.parentgrid = grdBook;

                    chpg.HouseCallBookData.ClearBook();
                    chpg.HouseCallBookData.CopyFromBook(book);

                    if (chpg.HouseCallBookData.ReadBook())
                    {
                        frmBooks.Navigate(chpg);
                        grdBook.Visibility = System.Windows.Visibility.Visible;
                    }

                    break;
                case BookTypes.MoveOut:
                    Pages.pgMoveOut mopg = new Pages.pgMoveOut();
                    mopg.MoveOutBook = book;
                    mopg.parentgrid = grdBook;

                    mopg.MoveOutBookData.ClearBook();
                    mopg.MoveOutBookData.CopyFromBook(book);

                    if (mopg.MoveOutBookData.ReadBook())
                    {
                        frmBooks.Navigate(mopg);
                        grdBook.Visibility = System.Windows.Visibility.Visible;
                    }

                    break;
                default:
                    break;
            }
        }

        private void lstBooks_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (lstBooks.SelectedItems.Count == 1)
            {
                Wins.winBook wnd = new Wins.winBook();
                wnd.bk = lstBooks.SelectedItem as Book;
                wnd.ShowDialog();
            }
        }

        private void bViewBook_Click(object sender, RoutedEventArgs e)
        {
            if (lstBooks.SelectedItems.Count == 1)
            {
                GotoBook(lstBooks.SelectedItem as Book);
            }
        }
        #endregion

        private void lstLocationBooks_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (lstLocationBooks.SelectedItems.Count == 1)
            {
                GotoBook(lstLocationBooks.SelectedItem as Book);
            }
        }



        












    }
}
